<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Simple Network</title>

    <script src="/js/alpinejs.min.js" defer></script>
    <link rel="stylesheet" href="/css/bulma.css" />
    <link rel="stylesheet" type="text/css" href="/css/admin.css" />
    <link rel="stylesheet" href="styles.css" />
    <style>
      .container {
        display: flex;
        justify-content: center;
      }
      .card-column {
        margin-bottom: 20px;
      }
    </style>
  </head>

  <body>
    <!-- START NAV -->
    <nav class="navbar is-black" x-data="{ isOpen: false }">
      <div class="container">
        <div class="navbar-brand">
          <a class="navbar-item brand-text" href="/"> Simple Admin </a>
          <a
            role="button"
            class="navbar-burger burger"
            @click="isOpen = !isOpen"
          >
            <span aria-hidden="true"></span>
            <span aria-hidden="true"></span>
            <span aria-hidden="true"></span>
          </a>
        </div>
        <div
          id="navMenu"
          class="navbar-menu"
          :class="isOpen ? 'is-active' : ''"
        >
          <div class="navbar-start">
            <a class="navbar-item" href="/"> Connection Info </a>
            <a class="navbar-item" href="/atcommander.html"> AT Commands </a>
            <a class="navbar-item" href="/bandlock.html"> Simple Network </a>
            <a class="navbar-item" href="/ttl.html"> TTL Changer </a>
            <a class="navbar-item" href="/speedtest.html"> OpenSpeedtest </a>
          </div>
        </div>
      </div>
    </nav>
    <!-- END NAV -->
    <div
      class="container"
      style="margin: auto"
      x-data="atCommands()"
      x-init="atCommands()"
    >
      <div class="columns is-multiline">
        <!-- First Box -->
        <div class="column is-8-tablet is-6-desktop card-column">
          <div class="card">
            <header class="card-header">
              <p class="card-header-title">Band Locking</p>
            </header>
            <div class="card-content">
              <!-- Create a drop down -->
              <div class="select is-primary">
                <select id="networkMode" x-model="networkMode">
                  <option>Select Network Mode</option>
                  <option>LTE</option>
                  <option>NR5G-NSA</option>
                  <option>NR5G-SA</option>
                </select>
              </div>
              <input
                class="input is-primary"
                type="text"
                placeholder="Example: 1,3,41"
                style="margin-top: 1rem"
                x-model="bandNumbers"
              />

              <div style="margin-top: 1rem; display: flex; flex-direction: row">
                <button
                  class="button is-primary"
                  @click="lockBands()"
                  :disabled="isLocking"
                >
                  Lock Bands
                </button>

                <button
                  class="button is-warning"
                  style="margin-left: 1rem"
                  @click="restoreBands()"
                  :disabled="isLocking"
                >
                  Restore Bands
                </button>
              </div>
            </div>
            <div class="card-footer" style="padding: 0.25rem">
              <p class="card-footer-item">
                Please first select your desired network band from the dropdown
                menu. To lock onto specific bands, please type the band numbers
                separated by commas (,) and then click the lock button.
              </p>
            </div>
          </div>
        </div>
        <!-- Second Box -->
        <div class="column is-8-tablet is-6-desktop card-column">
          <div class="card">
            <header class="card-header">
              <p class="card-header-title">LTE and NR5G Cell Locking</p>
            </header>
            <div class="card-content">
              <div style="display: flex; flex-direction: row">
                <div class="select is-info">
                  <select id="networkModeSelect" x-model="networkMode2">
                    <option>Select Network Mode</option>
                    <option>LTE</option>
                    <option>NR5G-SA</option>
                  </select>
                </div>

                <div
                  id="numFreqContainer"
                  style="margin-left: 1rem"
                  x-show="networkMode2 == 'LTE'"
                >
                  <input
                    class="input is-info"
                    type="number"
                    id="numFreqInput"
                    min="1"
                    max="10"
                    placeholder="1-10"
                    x-model="cellNum"
                  />
                </div>
              </div>

              <div id="freqNumbersContainer"></div>

              <!-- For NR5G-SA -->
              <div style="margin-top: 1rem" x-show="networkMode2 == 'NR5G-SA'">
                <div style="display: flex; flex-direction: row">
                  <input
                    class="input is-info"
                    type="text"
                    placeholder="EARFCN"
                    x-model="earfcn1"
                  />
                  <input
                    class="input is-info"
                    type="text"
                    placeholder="PCI"
                    x-model="pci1"
                    style="margin-left: 1rem"
                  />
                  <input
                    class="input is-info"
                    type="text"
                    placeholder="SCS"
                    x-model="scs"
                    style="margin-left: 1rem"
                  />
                  <input
                    class="input is-info"
                    type="text"
                    placeholder="BAND"
                    x-model="band"
                    style="margin-left: 1rem"
                  />
                </div>
              </div>

              <div style="margin-top: 1rem; display: flex; flex-direction: row">
                <button
                  class="button is-info"
                  @click="cellLock()"
                  :disabled="isLocking"
                >
                  Lock Cell
                </button>

                <button
                  class="button is-warning"
                  style="margin-left: 1rem"
                  @click="restoreCell()"
                  :disabled="isLocking"
                >
                  Restore Cell
                </button>
              </div>
            </div>
            <div class="card-footer" style="padding: 0.25rem">
              <p class="card-footer-item">
                To utilize cell locking, first, select the network mode, then
                specify the number of cells you wish to lock onto (max 10) if
                you are using LTE. Next, input the EARFCN and PCI values for
                each cell number. If you are locking through NR5G-SA instead,
                simply fill up all the required parameters.
              </p>
            </div>
          </div>
        </div>

        <!-- Third Box -->

        <div class="column is-8-tablet is-6-desktop card-column">
          <div class="card">
            <header class="card-header">
              <p class="card-header-title">Network Utilities</p>
            </header>
            <div class="card-content">
              <div style="display: flex; flex-direction: column">
                <div>
                  <p>Set Network APN</p>
                  <div
                    style="
                      display: flex;
                      flex-direction: row;
                      margin-top: 0.5rem;
                    "
                  >
                    <input
                      class="input is-link"
                      type="text"
                      placeholder="APN"
                      x-model="apnInput"
                    />
                    <button
                      class="button is-link"
                      style="margin-left: 1rem"
                      @click="setAPN()"
                      :disabled="isLoading"
                    >
                      Set APN
                    </button>
                  </div>
                </div>
              </div>

              <div style="margin-top: 1rem">
                <p>Set Preferred Network Mode</p>
                <div
                  style="display: flex; flex-direction: row; margin-top: 0.5rem"
                >
                  <div class="select is-info">
                    <select id="prefNetworkMode" x-model="prefNetworkMode">
                      <option>Select Network</option>
                      <option>AUTO</option>
                      <option>WCDMA</option>
                      <option>LTE ONLY</option>
                      <option>NR5G-NSA</option>
                      <option>NR5G-SA</option>
                    </select>
                  </div>

                  <button
                    class="button is-link"
                    style="margin-left: 1rem"
                    @click="setPrefNetwork()"
                    :disabled="isLoading"
                  >
                    Set Network
                  </button>
                </div>
              </div>

              <div style="margin-top: 1rem">
                <p>Set Sim Slot</p>
                <div
                  style="display: flex; flex-direction: row; margin-top: 0.5rem"
                >
                  <div class="select is-info">
                    <select id="simSlot" x-model="simSlot">
                      <option>Select Sim</option>
                      <option>1</option>
                      <option>2</option>
                    </select>
                  </div>

                  <button
                    class="button is-link"
                    style="margin-left: 1rem"
                    @click="setSimSlot()"
                    :disabled="isLoading"
                  >
                    Set Sim
                  </button>
                </div>
              </div>

              <div style="margin-top: 1rem">
                <p>NR5G Mode Control</p>
                <div
                  style="display: flex; flex-direction: row; margin-top: 0.5rem"
                >
                  <div class="select is-info">
                    <select id="nrMode" x-model="nrMode">
                      <option>Select NR5G Mode</option>
                      <option>Enable All</option>
                      <option>Disable NSA</option>
                      <option>Disable SA</option>
                    </select>
                  </div>

                  <button
                    class="button is-link"
                    style="margin-left: 1rem"
                    @click="nr5GMode()"
                    :disabled="isLoading"
                  >
                    Set Mode
                  </button>
                </div>
              </div>
            </div>
            <div class="card-footer" style="padding: 0.25rem">
              <p class="card-footer-item">
                This section allows you to set the APN, preferred network mode,
                and sim slot. Simply input the desired values and click the
                respective buttons to apply the changes. (Sim slot is only
                applicable for dual sim devices.)
              </p>
            </div>
          </div>
        </div>

        <!-- Fourth Box -->
        <div class="column is-8-tablet is-6-desktop card-column">
          <div class="card">
            <header class="card-header">
              <p class="card-header-title">Query Network Parameters</p>
            </header>
            <div class="card-content">
              <textarea
                class="textarea"
                rows="5"
                placeholder="Query Response"
                x-text=" isLoading ? 'Getting Response...' : queryCommandResponse"
              ></textarea>

              <div style="margin-top: 1.5rem">
                <p>Check Locked Bands</p>
                <div class="select is-info" style="margin-top: 0.5rem">
                  <select id="lockedBands" x-model="lockedBands">
                    <option>Locked Bands</option>
                    <option>LTE</option>
                    <option>NSA</option>
                    <option>SA</option>
                  </select>
                </div>

                <button
                  class="button is-link"
                  style="margin-left: 1rem; margin-top: 0.5rem"
                  @click="showLockedBands()"
                  :disabled="isLoading"
                >
                  Check Bands
                </button>
              </div>

              <div style="margin-top: 1rem">
                <p>Check Cell Lock</p>
                <div class="select is-info" style="margin-top: 0.5rem">
                  <select id="cellState" x-model="cellState">
                    <option>Cell Lock</option>
                    <option>LTE</option>
                    <option>NR5G-SA</option>
                  </select>
                </div>

                <button
                  class="button is-link"
                  style="margin-left: 1rem; margin-top: 0.5rem"
                  @click="showCellState()"
                  :disabled="isLoading"
                >
                  Check Cell
                </button>
              </div>

              <div style="margin-top: 2rem">
                <p>Other Network Query</p>
              </div>
              <div class="buttons" style="margin-top: 0.5rem">
                <button
                  class="button is-link mr-2"
                  @click="showSupportedBands()"
                  :disabled="isLoading"
                >
                  Show Supported Bands
                </button>

                <button
                  class="button is-link mr-2"
                  @click="showCurrentSim()"
                  :disabled="isLoading"
                >
                  Show Current Sim
                </button>

                <button
                  class="button is-link"
                  @click="showPrefNetwork()"
                  :disabled="isLoading"
                >
                  Show Pref Network
                </button>

                <button
                  class="button is-link"
                  @click="showCaInfo()"
                  :disabled="isLoading"
                >
                  Carrier Aggregation Info
                </button>

                <button
                  class="button is-link"
                  @click="servingCellInfo()"
                  :disabled="isLoading"
                >
                  Serving Cell Info
                </button>

                <button
                  class="button is-link"
                  @click="scanNeighbourCells()"
                  :disabled="isLoading"
                >
                  Scan Neighbour Cells
                </button>

                <button
                  class="button is-link"
                  @click="scanNsaCells()"
                  :disabled="isLoading"
                >
                  Scan NSA Cells
                </button>

                <button
                  class="button is-link"
                  @click="fullNetworkScan()"
                  :disabled="isLoading"
                >
                  Full Network Scan
                </button>
              </div>
            </div>
            <div class="card-footer" style="padding: 0.25rem">
              <p class="card-footer-item">
                This section allows you to query the network parameters. Simply
                click the respective buttons to view the network parameters.
              </p>
            </div>
          </div>
        </div>
      </div>

      <!-- Loading Modal for Locking Band -->
      <div x-show="isLocking" class="modal-overlay">
        <div class="loading-modal">
          <div class="spinner"></div>
          <div
            class="loading-text"
            style="display: flex; flex-direction: column"
          >
            <h3>Initializing Network...</h3>
            <p style="margin-top: 0.5rem">
              Please wait for
              <span x-text="countdown" style="font-weight: 500"></span> seconds.
            </p>
          </div>
        </div>
      </div>

      <div x-show="isError" class="modal-overlay">
        <div class="loading-modal">
          <div class="spinner"></div>
          <div
            class="loading-text"
            style="display: flex; flex-direction: column"
          >
            <h3>Request Error</h3>
            <p style="margin-top: 0.5rem">
              Please follow the instructions properly. Exiting in
              <span x-text="countdown" style="font-weight: 500"></span> seconds.
            </p>
          </div>
        </div>
      </div>
    </div>

    <script>
      function atCommands() {
        return {
          isLoading: false,
          isQuerying: false,
          isLocking: false,
          isError: false,
          countdown: 5, // Initial countdown value
          networkMode: null,
          networkMode2: null,
          bandNumbers: null,
          cellNum: null,
          earfcn1: null,
          pci1: null,
          earfcn2: null,
          pci2: null,
          earfcn3: null,
          pci3: null,
          earfcn4: null,
          pci4: null,
          earfcn5: null,
          pci5: null,
          earfcn6: null,
          pci6: null,
          earfcn7: null,
          pci7: null,
          earfcn8: null,
          pci8: null,
          earfcn9: null,
          pci9: null,
          earfcn10: null,
          pci10: null,
          band: null,
          scs: null,
          apnInput: null,
          prefNetworkMode: null,
          simSlot: null,
          nrMode: null,
          lockedBands: null,
          cellState: null,
          invalidCellNum: "",
          atCommandResponse: "",
          queryCommandResponse: "",
          lockBands() {
            if (!this.networkMode || !this.bandNumbers) {
              this.isError = true;
              this.startCountdown();
              console.error("Network mode and band numbers are required.");
              return;
            }

            // Remove commas and replace with colons
            const parsedBandNumbers = this.bandNumbers.replace(/,/g, ":");

            // Construct the atcmd based on the selected network mode
            let atcmd;
            switch (this.networkMode) {
              case "LTE":
                atcmd = `AT+QNWPREFCFG="lte_band",${parsedBandNumbers}`;
                console.log(atcmd);
                break;
              case "NR5G-NSA":
                atcmd = `AT+QNWPREFCFG="nsa_nr5g_band",${parsedBandNumbers}`;
                console.log(atcmd);
                break;
              case "NR5G-SA":
                atcmd = `AT+QNWPREFCFG="nr5g_band",${parsedBandNumbers}`;
                console.log(atcmd);
                break;
              default:
                console.error("Invalid network mode.");
                return;
            }

            this.isLoading = true;
            fetch(
              "/cgi-bin/get_atcommand?" +
                new URLSearchParams({
                  atcmd: atcmd,
                })
            )
              .then((res) => res.text())
              .then((data) => {
                this.atCommandResponse = data;
                this.isLocking = true;
                this.startCountdown();
              })
              .catch((error) => {
                this.isError = true;
                this.startCountdown();
                console.error("Error sending AT command:", error);
              })
              .finally(() => {
                this.isLoading = false;
              });
          },
          cellLock() {
            // Error handlers
            if (!this.networkMode2) {
              this.isError = true;
              this.startCountdown();
              console.error("Network mode is required.");
              return;
            }

            // Construct the AT command based on the selected network mode
            let atcmd;

            if (this.networkMode2 === "LTE") {
              if (parseInt(this.cellNum) > 10) {
                this.invalidCellNum = "Invalid";
                this.isError = true;
                this.startCountdown();
                console.error("Invalid frequency number.");
                return;
              }

              this.isLocking = true;
              atcmd = `AT+QNWLOCK="common/4g",${this.cellNum}`;
              for (let i = 1; i <= parseInt(this.cellNum); i++) {
                atcmd += `,${this["earfcn" + i]},${this["pci" + i]}`;
              }
              console.log(atcmd);
            } else if (this.networkMode2 === "NR5G-SA") {
              this.isLocking = true;
              atcmd = `AT+QNWLOCK="common/5g",${this.pci1},${this.earfcn1},${this.scs},${this.band}`;
              console.log(atcmd);
            }

            this.sendAtCommand(atcmd);
          },
          restoreBands() {
            const restoreCmd = 'AT+QNWPREFCFG="restore_band"';
            this.sendAtCommand(restoreCmd);
          },
          restoreCell() {
            const restoreCmd = 'AT+QNWLOCK="common/4g",0';
            this.sendAtCommand(restoreCmd);
          },
          setAPN() {
            const apnCmd = `AT+CGDCONT=1,"IPV4V6","${this.apnInput}"`;
            this.sendAtCommand(apnCmd);
          },
          setPrefNetwork() {
            // AT+QNWPREFCFG="mode_pref",<mode>
            let prefCmd;
            switch (this.prefNetworkMode) {
              case "AUTO":
                prefCmd = 'AT+QNWPREFCFG="mode_pref",AUTO';
                break;
              case "WCDMA":
                prefCmd = 'AT+QNWPREFCFG="mode_pref",WCDMA';
                break;
              case "LTE ONLY":
                prefCmd = 'AT+QNWPREFCFG="mode_pref",LTE';
                break;
              case "NR5G-NSA":
                prefCmd = 'AT+QNWPREFCFG="mode_pref",LTE:NR5G';
                break;
              case "NR5G-SA":
                prefCmd = 'AT+QNWPREFCFG="mode_pref",NR5G';
                break;
              default:
                console.error("Invalid network mode.");
                return;
            }
            this.sendAtCommand(prefCmd);
          },
          setSimSlot() {
            const simCmd = `AT+QUIMSLOT=${this.simSlot}`;
            this.sendAtCommand(simCmd);
          },
          nr5GMode() {
            let nrCmd;
            switch (this.nrMode) {
              case "Enable All":
                nrCmd = 'AT+QNWPREFCFG="nr5g_disable_mode",0';
                break;
              case "Disable NSA":
                nrCmd = 'AT+QNWPREFCFG="nr5g_disable_mode",2';
                break;
              case "Disable SA":
                nrCmd = 'AT+QNWPREFCFG="nr5g_disable_mode",1';
                break;
              default:
                console.error("Invalid NR5G mode.");
                return;
            }
            this.queryATCommand(nrCmd);
          },
          showLockedBands() {
            let lockedCmd;
            switch (this.lockedBands) {
              case "LTE":
                lockedCmd = 'AT+QNWPREFCFG="lte_band"';
                break;
              case "NSA":
                lockedCmd = 'AT+QNWPREFCFG="nsa_nr5g_band"';
                break;
              case "SA":
                lockedCmd = 'AT+QNWPREFCFG="nr5g_band"';
                break;
              default:
                console.error("Invalid network mode.");
                return;
            }
            this.queryATCommand(lockedCmd);
          },

          showCellState() {
            let cellCmd;
            switch (this.cellState) {
              case "LTE":
                cellCmd = 'AT+QNWLOCK="common/4g"';
                break;
              case "NR5G-SA":
                cellCmd = 'AT+QNWLOCK="common/5g"';
                break;
              default:
                console.error("Invalid network mode.");
                return;
            }
            this.queryATCommand(cellCmd);
          },
          showSupportedBands() {
            const supportedCmd = 'AT+QNWPREFCFG="policy_band"';
            this.queryATCommand(supportedCmd);
          },
          showCurrentSim() {
            const simCmd = "AT+QUIMSLOT?";
            this.queryATCommand(simCmd);
          },
          showPrefNetwork() {
            const prefCmd = 'AT+QNWPREFCFG="mode_pref"';
            this.queryATCommand(prefCmd);
          },
          showCaInfo() {
            const caCmd = "AT+QCAINFO";
            this.queryATCommand(caCmd);
          },
          servingCellInfo() {
            const servingCmd = 'AT+QENG="servingcell"';
            this.queryATCommand(servingCmd);
          },
          scanNeighbourCells() {
            const scanCmd = 'AT+QENG="neighbourcell"';
            this.queryATCommand(scanCmd);
          },
          scanNsaCells() {
            const enableCmd = 'AT+QNWCFG="nr5g_meas_info",1';
            const queryScanCmd = 'AT+QNWCFG="nr5g_meas_info"';
            // Send the enable command first without getting the response
            fetch(
              "/cgi-bin/get_atcommand?" +
                new URLSearchParams({
                  atcmd: enableCmd,
                })
            )
              .then(() => {
                console.log("Enable Success.");
                // Show a temporary loading query message
                this.queryCommandResponse =
                  "Enabling NSA cell scan. Please wait...";
                this.queryATCommand(queryScanCmd);
              })
              .catch((error) => {
                this.isError = true;
                this.startCountdown();
                console.error("Error sending AT command:", error);
              });
          },
          fullNetworkScan() {
            const scanCmd = "AT+QSCAN=3,1";
            // Show a temporary loading query message
            this.queryCommandResponse =
              "Full network scan initiated. This takes about a minute. Please wait...";
            this.queryATCommand(scanCmd);
          },
          queryATCommand(atcmd) {
            this.isQuerying = true;
            fetch(
              "/cgi-bin/get_atcommand?" +
                new URLSearchParams({
                  atcmd: atcmd,
                })
            )
              .then((res) => res.text())
              .then((data) => {
                this.queryCommandResponse = data;
                console.log(data);
              })
              .catch((error) => {
                this.isError = true;
                this.startCountdown();
                console.error("Error sending AT command:", error);
              })
              .finally(() => {
                this.isQuerying = false;
              });
          },
          sendAtCommand(atcmd) {
            this.isLoading = true;
            this.startCountdown();
            console.log(atcmd);
            fetch(
              "/cgi-bin/get_atcommand?" +
                new URLSearchParams({
                  atcmd: atcmd,
                })
            )
              .then((res) => res.text())
              .then((data) => {
                this.atCommandResponse = data;
                console.log(data);
              })
              .catch((error) => {
                this.isError = true;
                this.startCountdown();
                console.error("Error sending AT command:", error);
              })
              .finally(() => {
                this.isLoading = false;
              });
          },
          startCountdown() {
            // Decrease countdown every second
            const interval = setInterval(() => {
              this.countdown--;
              if (this.countdown <= 0) {
                clearInterval(interval);
                // Reset values
                this.isLocking = false;
                this.isError = false;
                this.isLoading = false;
                this.isQuerying = false;
                this.countdown = 5;
              }
            }, 1000);
          },
        };
      }

      const freqNumbersContainer = document.getElementById(
        "freqNumbersContainer"
      );

      function generateFreqNumberInputs(num) {
        let html = "";
        const maxFields = Math.min(num, 10); // Limit to a maximum of 10 fields
        for (let i = 1; i <= maxFields; i++) {
          html += `
        <div style="margin-top: 1rem" x-show="cellNum >= ${i} && networkMode2 == 'LTE'">
            <div style="display: flex; flex-direction: row">
                <input class="input is-info" type="text" placeholder="EARFCN" x-model="earfcn${i}" />
                <input class="input is-info" type="text" placeholder="PCI" x-model="pci${i}" style="margin-left: 1rem" />
            </div>
        </div>
      `;
        }
        return html;
      }

      document
        .getElementById("numFreqInput")
        .addEventListener("input", function () {
          const cellNum = parseInt(this.value);
          freqNumbersContainer.innerHTML = generateFreqNumberInputs(cellNum);
        });
    </script>
  </body>
</html>
